<?php

namespace app\services;

use app\payment\PayFactory;
use app\traits\Page;
use plugin\admin\app\model\ContributionToBalanceLog;
use plugin\admin\app\model\OrderCountRate;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserProfile;
use plugin\admin\app\model\UserProperty;
use plugin\admin\app\model\UserPropertyLog;
use plugin\admin\app\model\UserTeam;
use support\Db;

class UserPropertyService
{
    public static function list($page, $length, $type = null, $timeRange = [], $amountType = 0)
    {
        $offset = ($page - 1) * $length;
        $query = UserPropertyLog::select(['id', 'amount', 'type', 'remark', 'created_time', 'source', 'from_user_id'])->where('user_id', get_user_id());

        if (!is_null($type)) {
            if ($type == PayFactory::FREEZE_INTEGRAL) {
                $query = $query->whereIn('type', [PayFactory::FREEZE_INTEGRAL, PayFactory::UNFREEZE_INTEGRAL]);
            } else {
                $query = $query->where('type', $type);
            }
        }

        if ($amountType > 0) {
            if ($amountType == 1) {
                $query = $query->where('amount', '>', 0);
            } else {
                $query = $query->where('amount', '<', 0);
            }
        }

        if (count($timeRange) > 1) {
            $query = $query->whereBetween('created_time', [$timeRange[0], $timeRange[1]]);
        }

        $count = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->orderByDesc('id')->get()->toArray();

        $fromUserIds = array_filter(array_column($list, 'from_user_id'));

        $users = User::select(['id', 'mobile'])->whereIn('id', $fromUserIds)->get()->toArray();
        $users = array_combine(
            array_column($users, 'id'),
            array_values($users)
        );

        foreach ($list as $key=>$item) {
            if ($type == PayFactory::FREEZE_INTEGRAL && $item['type'] == PayFactory::UNFREEZE_INTEGRAL) {
                $list[$key]['amount'] = -$item['amount'];
            }
            $list[$key]['source_text'] = UserPropertyLog::getSourceText($item['source']);

            if (!empty($item['from_user_id']) && isset($users[$item['from_user_id']])) {
                $list[$key]['from_user_info'] = $users[$item['from_user_id']];
            }
        }

        return Page::wrap($count, $page, $length, $list);
    }

    public static function getRange($type, $timeRange = [])
    {
        $query = UserPropertyLog::select(['id', 'amount', 'remark', 'created_time', 'source'])->where('user_id', get_user_id())->where('type', $type);;

        if (count($timeRange) > 1) {
            $query = $query->whereBetween('created_time', [$timeRange[0], $timeRange[1]]);
        }

        $outcome = abs((clone $query)->where('amount', '<', 0)->sum('amount'));
        $income = $query->where('amount', '>', 0)->sum('amount');

        return ['total_income' => $income, 'total_outcome' => $outcome];
    }

    public static function getOrderCanUseIntegral($cartItemIds)
    {
        $cartItems = ShoppingCartService::list($cartItemIds, 1);

        if (empty($cartItems['list']['valid'])) {
            return 0;
        }

        $goodsIds = array_column($cartItems['list']['valid'], 'goods_id');

        if (GoodsService::isGift($goodsIds[0])) {
            return 0;
        }

        $propertyInfo = UserProperty::where('user_id', get_user_id())->first();

        return $propertyInfo['integral'];
    }

    public static function clearContribution()
    {
        $propertyList = UserProperty::where('contribution', '>', 0)->get()->toArray();

        foreach ($propertyList as $propertyInfo) {
            //根据当月直推订单数获取转换率
            $rate = self::getContributionToBalanceRate($propertyInfo['user_id']);

            //贡献值转余额
            $balance = bcmul($propertyInfo['contribution'], $rate / 100, 2);

            $desc = '';
            if ($rate == 0) {
                $desc = '贡献值转余额比例为0';
            }

            $teamInfo = UserTeam::where('user_id', $propertyInfo['user_id'])->first();

            //当月下单数量
            $giftOrderCount = OrderService::getRangeTimeGiftOrderCount(date('Y-m-01 00:00:00', strtotime('-1 month')), date('Y-m-t', strtotime('-1 month')), $propertyInfo['user_id']);

            if ($giftOrderCount == 0) {
                $desc = '当月无下单';
            }

            $status = ContributionToBalanceLog::FAIL;
            if ($balance > 0 && $giftOrderCount > 0) {
                $maxExchangeBalance = ConfigService::get('max_exchange_balance');

                $balance = $balance > $maxExchangeBalance ? $maxExchangeBalance : $balance;

                $status = ContributionToBalanceLog::SUCCESS;
                PropertyService::add($propertyInfo['user_id'], PayFactory::BALANCE, $balance, UserPropertyLog::CONTRIBUTION_TO_BALANCE);
            }

            //清空贡献值
            PropertyService::reduce($propertyInfo['user_id'], PayFactory::CONTRIBUTION, $propertyInfo['contribution'], UserPropertyLog::SYSTEM_CLEAR_CONTRIBUTION);

            ContributionToBalanceLog::insert([
                'user_id' => $propertyInfo['user_id'],
                'contribution' => $propertyInfo['contribution'],
                'rate' => $rate,
                'status' => $status,
                'desc' => $desc,
                'gift_order_count' => $giftOrderCount,
                'current_month_recommend_order_count' => $teamInfo['current_month_recommend_order_count'],
                'created_time' => date('Y-m-d H:i:s'),
            ]);
        }
    }

    public static function extraRebate()
    {
        $config = ConfigService::getByGroup('recommend');
        $rebateConfig = ConfigService::getByGroup('rebate');
        $teams = UserTeam::where('current_month_recommend_order_count', '>=', $config['recommend_count_limit'])->get()->toArray();

        foreach ($teams as $team) {
            $userId = $team['user_id'];

            $children = User::where('parent_id', $userId)->get()->toArray();

            $childrenUserIds = array_column($children, 'id');

            $totalAmount = UserPropertyLog::whereIn('user_id', $childrenUserIds)->where('source', UserPropertyLog::CONTRIBUTION_TO_BALANCE)->whereBetween('created_time', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')])->sum('amount');

            $extraAmount = bcmul($rebateConfig['extra_rate'] / 100, $totalAmount, 2);

            if ($extraAmount > 0) {
                PropertyService::add($userId, PayFactory::BALANCE, $extraAmount, UserPropertyLog::EXTRA_REBATE);
            }
        }
    }

    public static function getContributionToBalanceRate($userId)
    {
        $teamInfo = UserTeam::where('user_id', $userId)->first();

        $rateInfo = OrderCountRate::where('min_count', '<=', $teamInfo['current_month_recommend_order_count'] ?? 0)->orderByDesc('id')->first();

        if (empty($rateInfo)) {
            return 0;
        }

        return $rateInfo['rate'];
    }
}